import Util from "../../../StartAb/Util";
import WXAD from "../../../StartAb/WXAd";
import EventCenter from "../../TFrame/script/helper/EventCenter";
import Coordinates from "../Coordinates";
import EventNames from "../EventNames";
import IconFramesMgr from "../IconFramesMgr";
import LevelLogic from "../logic/LevelLogic";
import NativeCaller from "../NativeCaller";
import { ActionType } from "../net/Enum";
import ServiceLogic from "../net/ServerLogic";
import PlayerDataMgr from "../PlayerDataMgr";
import ResManager from "../ResManager";
import GardenSystem, { PlantStage } from "./GardenSystem";

/**
 * *初始化场景
 * *建造 升级
 * *金币
 * *粒子
 * *音效
 */
const { ccclass, property } = cc._decorator;

@ccclass
export default class GardenScene extends cc.Component {

    @property(cc.SpriteAtlas)
    flowerAtlas: cc.SpriteAtlas = null;

    @property(cc.Label)
    ownSunshineLabel: cc.Label = null;

    @property(cc.Node)
    buildTipRootNode: cc.Node = null;

    @property(cc.Label)
    buildNeedSunshineLabel: cc.Label = null;

    @property(cc.Node)
    sunIconNode: cc.Node = null;

    @property(cc.SpriteFrame)
    flySunFrame: cc.SpriteFrame = null;

    @property(cc.Prefab)
    upgradeButtonPrefab: cc.Prefab = null;

    @property(cc.Prefab)
    flowerParticle: cc.Prefab = null;

    @property(cc.AudioClip)
    outCoinAudio: cc.AudioClip = null;

    @property(cc.AudioClip)
    plantAudio: cc.AudioClip = null;

    flowerCntAFloor = 4;

    flowerIdxTimerLabelMap = {} as { string: cc.Label };

    onLoad() {
        this.buildTipRootNode.active = false;
        this.updateSunshineLabel();
    }
    start() {
        this.init();

        EventCenter.on(EventNames.PlantUpgraded, (flowerIdx: number) => {
            this.upgradePlant(flowerIdx)
        }, this)

        EventCenter.on(EventNames.PlantCoinCollected, (flowerIdx: number) => {
            GardenSystem.didCollectCoin(flowerIdx)
            this.initTimer(flowerIdx);
        }, this)

        this.schedule(this.schedulePerSecond, 1.0)
    }

    updateSunshineLabel() {
        this.ownSunshineLabel.string = GardenSystem.yourSunshine.toString()
    }

    init() {
        for (let floor = 0; floor < 2; ++floor) {
            let floorNode = this.node.getChildByName("floor" + floor)
            if (floorNode == null)
                break;
            for (let idxInFloor = 0; idxInFloor < this.flowerCntAFloor; ++idxInFloor) {
                let flowerIdx = floor * this.flowerCntAFloor + idxInFloor;
                let flowerRootNode = floorNode.getChildByName(flowerIdx.toString()); //第二层需要命令 4 5 6 7
                if (flowerRootNode == null)
                    break;
                this.initFlowerSprite(flowerIdx)
                this.initTimer(flowerIdx)
                this.initWaitPlantPot(flowerRootNode, flowerIdx)
                this.updateUpgradeButton(flowerIdx)
                let stage = GardenSystem.getPlantState(flowerIdx);
                this.potGrayOrNot(flowerRootNode.getChildByName('pot'), stage == 0);
            }
        }
    }

    schedulePerSecond() {
        for (let i = 0; i < GardenSystem.PotCount; ++i) {
            let lb = this.flowerIdxTimerLabelMap[i.toString()] as cc.Label;
            if (lb != null) {
                let leftTimeMs = GardenSystem.getLeftTimeInMillSecond(i)
                if (leftTimeMs > 0) {
                    lb.string = Util.secondToStr(Math.round(leftTimeMs / 1000), false)
                } else {
                    this.generateCoinFruit(i);
                    this.flowerIdxTimerLabelMap[i.toString()] = null;
                    lb.node.destroy();
                }
            }
        }
    }

    getFlowerRootNode(flowerIdx: number) {
        if (flowerIdx < 0 || flowerIdx >= GardenSystem.PotCount)
            return null;
        let floor = Math.floor(flowerIdx / 4);
        let floorNode = this.node.getChildByName("floor" + floor)
        if (floorNode == null)
            return null;
        let flowerRootNode = floorNode.getChildByName(flowerIdx.toString());
        return flowerRootNode;
    }

    getFlowerSpriteNode(flowerIdx: number) {
        let flowerRootNode = this.getFlowerRootNode(flowerIdx)
        if (flowerRootNode == null)
            return null
        return flowerRootNode.getChildByName("flower");
    }

    initFlowerSprite(flowerIdx: number) {
        let flowerRootNode = this.getFlowerRootNode(flowerIdx)
        if (flowerRootNode == null)
            return null
        let flowerSpriteNode = flowerRootNode.getChildByName("flower")
        let stage = GardenSystem.getPlantState(flowerIdx);
        flowerSpriteNode.active = stage >= PlantStage.SmallPant;
        if (stage >= PlantStage.SmallPant) {
            flowerSpriteNode.getComponent(cc.Sprite).spriteFrame = this.flowerAtlas.getSpriteFrame(GardenSystem.getPlantName(flowerIdx) + "_" + stage);
            if (stage == PlantStage.BigPlant) {
                let parNode = cc.instantiate(this.flowerParticle);
                parNode.parent = flowerRootNode;
                parNode.position = cc.v3(0, 40)
            }
        }
    }

    initTimer(flowerIdx: number) {
        let flowerRootNode = this.getFlowerRootNode(flowerIdx)
        if (flowerRootNode == null)
            return null
        if (GardenSystem.getPlantState(flowerIdx) < PlantStage.BigPlant)
            return console.log(`花儿${flowerIdx + 1}等级不够`);
        let leftTimeMs = GardenSystem.getLeftTimeInMillSecond(flowerIdx)
        if (leftTimeMs > 0) {
            let n = new cc.Node;
            let lb = n.addComponent(cc.Label);
            lb.fontSize = 26;
            n.setPosition(-5, -30);
            lb.enableBold = true;
            n.color = cc.Color.GREEN
            n.parent = flowerRootNode;
            lb.string = Util.secondToStr(Math.round(leftTimeMs / 1000), false)
            this.flowerIdxTimerLabelMap[flowerIdx.toString()] = lb;
        } else {
            this.generateCoinFruit(flowerIdx, false)
        }
    }

    initWaitPlantPot(flowerRootNode: cc.Node, flowerIdx: number) {
        if (flowerRootNode == null)
            return;
        if (GardenSystem.getPlantState(flowerIdx) == PlantStage.WaitPlant) {
            let sunshine = GardenSystem.getPlantSunshineCnt(flowerIdx);
            this.buildNeedSunshineLabel.string = sunshine.toString();
            this.buildTipRootNode.parent = flowerRootNode;
            this.buildTipRootNode.position = cc.v3(0, 100);
            this.buildTipRootNode.active = true;
            cc.tween(this.buildTipRootNode)
                .set({ scale: 0 })
                .to(0.5, { scale: 1.0 })
                .call(() => {
                    let stage = GardenSystem.getPlantState(flowerIdx);
                    this.potGrayOrNot(flowerRootNode.getChildByName('pot'), stage == 0);
                })
                .start()
        }
    }

    updateUpgradeButton(flowerIdx: number) {
        let flowerRootNode = this.getFlowerRootNode(flowerIdx)
        if (flowerRootNode == null)
            return;
        if (GardenSystem.getPlantState(flowerIdx) == PlantStage.SmallPant) {
            let btn = cc.instantiate(this.upgradeButtonPrefab);
            btn.name = flowerIdx.toString();
            btn.parent = flowerRootNode;
            btn.setPosition(cc.v2(-10, -35));
        }
    }

    potGrayOrNot(pot: cc.Node, gray: boolean) {
        if (pot == null)
            return;
        let spr = pot.getComponent(cc.Sprite);
        spr.setMaterial(0, gray ? cc.Material.getBuiltinMaterial('2d-gray-sprite') :
            cc.Material.getBuiltinMaterial('2d-sprite'))
    }

    buildClicked(e: cc.Event.EventTouch) {
        let sunshineNeed = GardenSystem.getPlantSunshineCnt(GardenSystem.getCurrentWaitFlowerIdx());
        if (GardenSystem.tryToConsumeSunshine(sunshineNeed) == true) {
            this.buildTipRootNode.scale = 0;
            this.buildTipRootNode.active = false;
            //fly sun shine ani
            this.flySunIconAni();
            ServiceLogic.action(ActionType.ActionPlantSuccess,
                {
                    "beiz": "花" + GardenSystem.getCurrentWaitFlowerIdx() + "-" + sunshineNeed,
                    "sun": GardenSystem.yourSunshine
                }
            )
            //show flower
        } else {
            //show sunshine not enough
            cc.assetManager.getBundle("GameAb").load("prefab/SunshineNotEnough", cc.Prefab, (err: Error, pf: cc.Prefab) => {
                if (err)
                    return console.log(err.message);
                if (this.isValid) {
                    let dialog = cc.instantiate(pf);
                    dialog.parent = this.node;
                }
            })
            ServiceLogic.action(ActionType.ActionPlantLackSun, { "beiz": "花" + GardenSystem.getCurrentWaitFlowerIdx() + " " + GardenSystem.yourSunshine + "/" + sunshineNeed })
        }
    }

    flySunIconAni() {
        let cnt = 3;
        for (let i = 0; i < cnt; ++i) {
            let n = new cc.Node();
            let spr = n.addComponent(cc.Sprite);
            spr.spriteFrame = this.flySunFrame;
            n.opacity = 0;
            n.setPosition(this.node.convertToNodeSpaceAR(this.sunIconNode.convertToWorldSpaceAR(cc.Vec2.ZERO)))
            n.parent = this.node;
            let targetPos = cc.v3(this.node.convertToNodeSpaceAR(this.buildTipRootNode.convertToWorldSpaceAR(cc.Vec2.ZERO))).add(cc.v3(0, - 50))
            cc.tween(n)
                .delay(i * 0.15)
                .set({ opacity: 255 })
                .to(0.5, { position: targetPos }, { easing: "quadIn" })
                .to(0.2, { opacity: 0 })
                .call(() => {
                    n.destroy();
                    if (i == cnt - 1) {
                        this.updateSunshineLabel();
                        this.buildOutFlower();
                    }
                })
                .start()
        }
    }

    buildOutFlower() {
        let flowerIdx = GardenSystem.getCurrentWaitFlowerIdx();
        GardenSystem.didPlantFlower(flowerIdx);
        let flowerSpriteNode = this.getFlowerSpriteNode(flowerIdx);
        if (flowerSpriteNode == null)
            return console.error("花朵sprite不该为空哦")
        flowerSpriteNode.scale = 0;

        flowerSpriteNode.getComponent(cc.Sprite).spriteFrame = this.flowerAtlas.getSpriteFrame(GardenSystem.getPlantName(flowerIdx) + "_" + PlantStage.SmallPant);
        flowerSpriteNode.active = true;
        cc.tween(flowerSpriteNode)
            .call(() => {
                this.plantAudio && (cc.audioEngine.playEffect(this.plantAudio, false))
            })
            .to(0.5, { scale: 1 })
            .call(() => {
                this.showNextWaitPlant();
                this.updateUpgradeButton(flowerIdx)
            })
            .start()
    }

    upgradePlant(flowerIdx: number) {
        let flowerSpriteNode = this.getFlowerSpriteNode(flowerIdx);
        if (flowerSpriteNode == null)
            return console.error("花朵sprite不该为空哦")
        this.plantAudio && (cc.audioEngine.playEffect(this.plantAudio, false))
        flowerSpriteNode.getComponent(cc.Sprite).spriteFrame = this.flowerAtlas.getSpriteFrame(GardenSystem.getPlantName(flowerIdx) + "_" + PlantStage.BigPlant);;
        flowerSpriteNode.active = true;

        this.initTimer(flowerIdx);
        let parNode = cc.instantiate(this.flowerParticle);
        parNode.parent = flowerSpriteNode.parent;
        parNode.position = cc.v3(0, 40)
        ServiceLogic.action(ActionType.ActionUpgradePlant, { "beiz": "花" + flowerIdx })
    }

    showNextWaitPlant() {
        let flowerIdx = GardenSystem.getCurrentWaitFlowerIdx();
        this.initWaitPlantPot(this.getFlowerRootNode(flowerIdx), flowerIdx)
    }

    generateCoinFruit(flowerIdx: number, withAni = true) {
        cc.assetManager.getBundle("GameAb").load("prefab/coinFruit", cc.Prefab, (err: Error, pf: cc.Prefab) => {
            if (err)
                return console.log(err.message);
            //fix临界情况
            if (this.isValid && this.node != null) {
                let node = cc.instantiate(pf);
                node.name = flowerIdx.toString();
                node.parent = this.getFlowerRootNode(flowerIdx);
                let targetPos = cc.v3(0, 210);
                if (withAni) {
                    node.setPosition(cc.v2(0, 0));
                    this.outCoinAudio && (cc.audioEngine.playEffect(this.outCoinAudio, false))
                    cc.tween(node)
                        .to(0.5, { position: targetPos }, { easing: "backIn" })
                        .call(() => {
                            EventCenter.emit("coinFruitReady")
                        })
                        .start();
                } else {
                    node.position = targetPos;
                    this.scheduleOnce(() => {
                        EventCenter.emit("coinFruitReady")
                    }, 0.1)
                }
            }
        })
    }

    homeClick(e: cc.Event.EventTouch) {
        Util.disableNodeButton(e.target)
        Util.changeScene("Home");
    }

    playClick(e: cc.Event.EventTouch) {
        Util.disableNodeButton(e.target)
        let currentPlayLevel = LevelLogic.getCurrentPlayLevel();
        let isHasNextLevel = (currentPlayLevel < ResManager.getLevelResArray().length);
        if (isHasNextLevel) {
            Coordinates.loadLvCoordinate(currentPlayLevel, () => {
                ResManager.currentLevelIndex = currentPlayLevel
                PlayerDataMgr.getInstance().setLastLevelIndex(currentPlayLevel)
                Util.changeScene("game");
                WXAD.instance.hideBanner();
            })
        } else {
            IconFramesMgr.getInstance().loadIcons(() => {
                Util.changeScene("levelList");
            })
        }
    }
}
